package com.gack.netty.dispatcher;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import com.gack.netty.util.common.ExceptionUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * Created by ycy on 16/1/13.
 * 自己扩展线程池获取异常位置
 * 重写submit:可以拉取异常
 */
@Slf4j
public class VeryTraceThreadPoolExecutor extends ThreadPoolExecutor {
 
    // 初始化
    public VeryTraceThreadPoolExecutor(int corePoolSize, int maxmumPoolSize,
                                       long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue){
        super(corePoolSize,maxmumPoolSize,keepAliveTime,unit,workQueue);
    }
    
    public static VeryTraceThreadPoolExecutor newFixedThreadPool(int nThreads) {
        return new VeryTraceThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
    
    //执行方法
    @Override
    public void execute(Runnable command) {
        super.execute(command);
    }
 
    @Override
    public Future<?> submit(Runnable task) {
        return super.submit(wrap(task,clientTrace(),Thread.currentThread().getName()));
    }
 
    private Exception clientTrace(){
        //扔出异常
        return new Exception("client stack trace");
    }
 
    private Runnable wrap(final Runnable task,final Exception clientStack,String clientThreadName){
 
        return  new Runnable() {
            public void run() {
            	
                try {
                    task.run();
                } catch (Exception e) {
                	log.error("-------------------------NETTY THREADPOOLEXECUTOR ERROR-------------------------");
            		log.error("线程["+clientThreadName+"] 出现异常");
            		log.error("异常信息>>" + e.toString());
            		log.error("堆栈信息>>");
            		String[] stackTraceArray = ExceptionUtil.getThrowableStrRep(clientStack);
            		for(String stackTrace : stackTraceArray){
            			log.error(stackTrace);
            		}
                    clientStack.printStackTrace();
                    try {
                        throw e;
                    } catch (Exception e1) {
                    	log.error("-------------------------NETTY THREADPOOLEXECUTOR ERROR-------------------------");
                		log.error("线程["+clientThreadName+"] 出现异常");
                		log.error("异常信息>>" + e.toString());
                		log.error("堆栈信息>>");
                		String[] stackTraceArray1 = ExceptionUtil.getThrowableStrRep(e1);
                		for(String stackTrace : stackTraceArray1){
                			log.error(stackTrace);
                		}
                        e1.printStackTrace();
                    }
                }
            }
        };
    }
 
    public static void main(String[] args) {
//        ThreadPoolExecutor pools=new VeryTraceThreadPoolExecutor(0,Integer.MAX_VALUE,0l,TimeUnit.SECONDS,new SynchronousQueue<Runnable>());
        //错误堆栈中可以看到是在哪里提交的任务
//        for (int i = 0; i < 5; i++) {
//            pools.execute(new DviTask(100,i));
//        }
    }
}
